import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';
import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind,
} from 'vscode-languageclient/node';

// 声明为全局变量，以便在其他地方可以访问
let client: LanguageClient;

export function startLanguageServer(context: ExtensionContext): Promise<LanguageClient> {
  // 明确指定返回的Promise类型为LanguageClient
  return new Promise<LanguageClient>((resolve, reject) => {
    try {
      // 语言服务器
      // --inspect=6009: 在Node的Inspector模式下运行服务器，以便VS Code可以附加到服务器上进行调试
      const serverModule = context.asAbsolutePath(
        path.join('server', 'out', 'server.js')
      );
      
      // 如果扩展是在调试模式下启动的，则使用调试服务器选项
      // 否则，将使用运行选项
      const serverOptions: ServerOptions = {
        run: { module: serverModule, transport: TransportKind.ipc },
        debug: {
          module: serverModule,
          transport: TransportKind.ipc,
        },
      };
      
      // 控制语言客户端的选项
      const clientOptions: LanguageClientOptions = {
        // 在服务器上注册文档
        documentSelector: [
          { scheme: 'file', language: 'plaintext' },
          { scheme: 'file', language: 'javascript' },
          { scheme: 'file', language: 'typescript' },
        ],
        // 配置文件来存储用户和项目的配置选项
        synchronize: {
          // 通知服务器有关工作区中包含的" .clientrc"文件的文件更改
          fileEvents: workspace.createFileSystemWatcher('**/.clientrc'),
        },
      };

      // 创建语言客户端，然后启动客户端
      client = new LanguageClient(
        'languageServerExample',
        'Language Server Example',
        serverOptions,
        clientOptions
      );
      
      // 启动客户端并返回
      client.start().then(() => {
        resolve(client);
      }).catch(error => {
        reject(error);
      });
      
    } catch (error) {
      reject(error);
    }
  });
}

// 导出客户端以便其他模块可以使用
export function getClient(): LanguageClient | undefined {
  return client;
}

// 停止语言服务器的函数
export async function stopLanguageServer(): Promise<void> {
  if (client) {
    await client.stop();
    client = undefined as any;
  }
}